"""
qinxus情绪提取优化模块
提供高性能的情绪提取和文本处理功能
"""

import re
import time
import logging
from typing import Dict, Tuple, Optional
from functools import lru_cache

logger = logging.getLogger(__name__)

# 预编译的正则表达式，避免重复编译
_QINXUS_COMPILED_PATTERN = re.compile(r'\.?\s*\{"qinxus":\s*"([^"]+)"\}')
_EMOTION_TAG_PATTERN = re.compile(r'\s*\{emotion:(\w+)\}\s*$')

# 简单的LRU缓存用于常见的情绪提取结果
_emotion_cache = {}
_cache_timestamps = {}
_CACHE_TTL = 300  # 5分钟缓存TTL
_MAX_CACHE_SIZE = 1000

# 情绪映射缓存，避免重复的字符串操作
_EMOTION_MAPPING = {
    "happy": "happy",
    "sad": "sad", 
    "angry": "angry",
    "fear": "fearful",
    "fearful": "fearful",
    "neutral": "neutral"
}

def _clean_cache():
    """清理过期的缓存条目"""
    current_time = time.time()
    expired_keys = [
        key for key, timestamp in _cache_timestamps.items()
        if current_time - timestamp > _CACHE_TTL
    ]
    
    for key in expired_keys:
        _emotion_cache.pop(key, None)
        _cache_timestamps.pop(key, None)

def _add_to_cache(text_hash: str, result: Tuple[str, str]):
    """添加结果到缓存"""
    # 如果缓存过大，清理一些条目
    if len(_emotion_cache) >= _MAX_CACHE_SIZE:
        _clean_cache()
        # 如果清理后仍然过大，删除最旧的条目
        if len(_emotion_cache) >= _MAX_CACHE_SIZE:
            oldest_key = min(_cache_timestamps.keys(), key=lambda k: _cache_timestamps[k])
            _emotion_cache.pop(oldest_key, None)
            _cache_timestamps.pop(oldest_key, None)
    
    _emotion_cache[text_hash] = result
    _cache_timestamps[text_hash] = time.time()

def extract_qinxus_emotion_optimized(text: str, use_cache: bool = True) -> Tuple[str, str]:
    """
    高性能版本的qinxus情绪提取
    
    Args:
        text: 包含情绪标识的文本
        use_cache: 是否使用缓存
        
    Returns:
        Tuple[str, str]: (纯文本, 情绪)
    """
    if not text:
        return text, "neutral"
    
    # 快速路径：如果文本中没有qinxus关键字，直接返回
    if 'qinxus' not in text:
        return text, "neutral"
    
    # 缓存检查（仅对较短的文本使用缓存）
    if use_cache and len(text) < 500:
        text_hash = hash(text)
        if text_hash in _emotion_cache:
            timestamp = _cache_timestamps.get(text_hash, 0)
            if time.time() - timestamp < _CACHE_TTL:
                return _emotion_cache[text_hash]
    
    try:
        # 使用预编译的正则表达式
        match = _QINXUS_COMPILED_PATTERN.search(text)
        
        if match:
            emotion = match.group(1)
            # 使用字符串切片而不是正则替换来提高性能
            match_start, match_end = match.span()
            clean_text = (text[:match_start] + text[match_end:]).strip()
            
            result = (clean_text, emotion)
            
            # 添加到缓存
            if use_cache and len(text) < 500:
                _add_to_cache(hash(text), result)
            
            return result
        else:
            result = (text, "neutral")
            
            # 添加到缓存
            if use_cache and len(text) < 500:
                _add_to_cache(hash(text), result)
                
            return result
            
    except Exception as e:
        logger.error(f"提取qinxus情绪时出错: {str(e)}")
        return text, "neutral"

def map_emotion_for_tts_optimized(emotion: str) -> str:
    """
    高性能版本的情绪映射
    
    Args:
        emotion: 原始情绪名称
        
    Returns:
        映射后的情绪名称
    """
    return _EMOTION_MAPPING.get(emotion, "neutral")

@lru_cache(maxsize=128)
def is_qinxus_text_cached(text: str) -> bool:
    """
    缓存版本的qinxus文本检测
    
    Args:
        text: 要检查的文本
        
    Returns:
        bool: 是否包含qinxus格式
    """
    return 'qinxus' in text and _QINXUS_COMPILED_PATTERN.search(text) is not None

def batch_extract_emotions(texts: list) -> list:
    """
    批量处理多个文本的情绪提取
    
    Args:
        texts: 文本列表
        
    Returns:
        list: 处理结果列表，每个元素为(纯文本, 情绪)元组
    """
    results = []
    
    for text in texts:
        result = extract_qinxus_emotion_optimized(text)
        results.append(result)
    
    return results

def get_cache_stats() -> Dict[str, int]:
    """
    获取缓存统计信息
    
    Returns:
        Dict: 缓存统计信息
    """
    return {
        "cache_size": len(_emotion_cache),
        "cache_capacity": _MAX_CACHE_SIZE,
        "cache_ttl": _CACHE_TTL
    }

def extract_emotion_tag(text: str) -> Tuple[str, str]:
    """
    提取{emotion:词汇}格式的情绪标识
    
    Args:
        text: 包含情绪标识的文本
        
    Returns:
        Tuple[str, str]: (纯文本, 情绪词)
    """
    if not text:
        return text, "neutral"
    
    try:
        # 查找情绪标识
        match = _EMOTION_TAG_PATTERN.search(text)
        
        if match:
            emotion = match.group(1).lower()
            # 验证情绪词是否在允许的列表中
            valid_emotions = {"happy", "sad", "angry", "fearful", "neutral"}
            if emotion not in valid_emotions:
                emotion = "neutral"
            
            # 移除情绪标识，保留纯文本
            clean_text = _EMOTION_TAG_PATTERN.sub("", text).strip()
            
            logger.debug(f"提取到情绪标识: {emotion}")
            return clean_text, emotion
        else:
            return text, "neutral"
            
    except Exception as e:
        logger.error(f"提取情绪标识时出错: {str(e)}")
        return text, "neutral"

def clear_cache():
    """清空所有缓存"""
    global _emotion_cache, _cache_timestamps
    _emotion_cache.clear()
    _cache_timestamps.clear() 